package neatlogic.module.change.operationauth.handler;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

import javax.annotation.PostConstruct;

import neatlogic.framework.change.constvalue.ChangeStatus;
import neatlogic.framework.change.dto.ChangeStepVo;
import neatlogic.framework.common.constvalue.SystemUser;
import neatlogic.framework.crossover.CrossoverServiceFactory;
import neatlogic.framework.process.constvalue.*;
import neatlogic.framework.process.crossover.IProcessTaskCrossoverService;
import neatlogic.framework.process.exception.operationauth.*;
import neatlogic.module.change.operationauth.exception.ProcessTaskChangeStepUndoneException;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import neatlogic.framework.process.dto.ProcessTaskStepVo;
import neatlogic.framework.process.dto.ProcessTaskVo;
import neatlogic.framework.process.operationauth.core.OperationAuthHandlerBase;
import neatlogic.framework.process.operationauth.core.TernaryPredicate;
import neatlogic.module.change.dao.mapper.ChangeMapper;
import neatlogic.framework.change.dto.ChangeVo;
import neatlogic.module.change.service.ChangeService;

@Component
public class ChangeHandleOperationAuthHandler extends OperationAuthHandlerBase {

    private final Map<ProcessTaskOperationType,
        TernaryPredicate<ProcessTaskVo, ProcessTaskStepVo, String, Map<Long, Map<ProcessTaskOperationType, ProcessTaskPermissionDeniedException>>, JSONObject>> operationBiPredicateMap = new HashMap<>();

    @Autowired
    private ChangeMapper changeMapper;

    @Autowired
    private ChangeService changeService;

    @PostConstruct
    public void init() {
        operationBiPredicateMap.put(ProcessTaskOperationType.STEP_COMPLETE, (processTaskVo, processTaskStepVo, userUuid, operationTypePermissionDeniedExceptionMap, extraParam) -> {
            Long id = processTaskVo.getId();
            ProcessTaskOperationType operationType = ProcessTaskOperationType.STEP_COMPLETE;
            //1.判断工单是否被隐藏，如果isShow=0，则提示“工单已隐藏”；
            if (processTaskVo.getIsShow() == 0) {
                operationTypePermissionDeniedExceptionMap.computeIfAbsent(id, key -> new HashMap<>())
                        .put(operationType, new ProcessTaskHiddenException());
                return false;
            }

            IProcessTaskCrossoverService processTaskCrossoverService = CrossoverServiceFactory.getApi(IProcessTaskCrossoverService.class);
            //2.判断工单状态是否是“已评分”，如果是，则提示“工单已评分”；
            //3.判断工单状态是否是“已完成”，如果是，则提示“工单已完成”；
            //4.判断工单状态是否是“已取消”，如果是，则提示“工单已取消”；
            //5.判断工单状态是否是“异常”，如果是，则提示“工单异常”；
            //6.判断工单状态是否是“已挂起”，如果是，则提示“工单已挂起”；
            ProcessTaskPermissionDeniedException exception = processTaskCrossoverService.checkProcessTaskStatus(processTaskVo.getStatus(),
                    ProcessTaskStatus.SUCCEED,
                    ProcessTaskStatus.ABORTED,
                    ProcessTaskStatus.FAILED,
                    ProcessTaskStatus.HANG,
                    ProcessTaskStatus.SCORED);
            if (exception != null) {
                operationTypePermissionDeniedExceptionMap.computeIfAbsent(id, key -> new HashMap<>())
                        .put(operationType, exception);
                return false;
            }
            //8.判断步骤是否未激活，如果isActive=0，则提示“步骤未激活”；
            if (processTaskStepVo.getIsActive() == 0) {
                operationTypePermissionDeniedExceptionMap.computeIfAbsent(id, key -> new HashMap<>())
                        .put(operationType, new ProcessTaskStepNotActiveException());
                return false;
            }
            //8.判断步骤状态是否是“已完成”，如果是，则提示“步骤已完成”；
            //9.判断步骤状态是否是“异常”，如果是，则提示“步骤异常”；
            //10.判断步骤状态是否是“已挂起”，如果是，则提示“步骤已挂起”；
            //11.判断步骤状态是否是“待处理”，如果是，则提示“步骤未开始”；
            exception = processTaskCrossoverService.checkProcessTaskStepStatus(processTaskVo.getStatus(), ProcessTaskStepStatus.SUCCEED,
                    ProcessTaskStepStatus.FAILED,
                    ProcessTaskStepStatus.HANG,
                    ProcessTaskStepStatus.PENDING);
            if (exception != null) {
                operationTypePermissionDeniedExceptionMap.computeIfAbsent(id, key -> new HashMap<>())
                        .put(operationType, exception);
                return false;
            }
            //12.判断当前步骤是否有下一步骤，如果没有，则提示“该步骤没有下一步骤”；
            if (!checkNextStepIsExistsByProcessTaskStepIdAndProcessFlowDirection(processTaskVo, processTaskStepVo.getId(), ProcessFlowDirection.FORWARD)) {
                operationTypePermissionDeniedExceptionMap.computeIfAbsent(id, key -> new HashMap<>())
                        .put(operationType, new ProcessTaskStepNotNextStepException());
                return false;
            }
            //13.判断变更步骤列表中是否有“待处理”或“处理中”的步骤，如果有，则提示“有变更步骤未完成”；
            Long changeId = changeMapper.getChangeIdByProcessTaskStepId(processTaskStepVo.getId());
            if (changeId != null) {
                ChangeVo changeVo = changeService.getChangeById(changeId);
                if (ChangeStatus.RUNNING.getValue().equals(changeVo.getStatus())) {
                    for (ChangeStepVo changeStepVo : changeVo.getChangeStepList()) {
                        if (Objects.equals(changeStepVo.getIsActive(), 0)
                                || ChangeStatus.PENDING.getValue().equals(changeStepVo.getStatus())
                                || ChangeStatus.RUNNING.getValue().equals(changeStepVo.getStatus())) {
                            operationTypePermissionDeniedExceptionMap.computeIfAbsent(id, key -> new HashMap<>())
                                    .put(operationType, new ProcessTaskChangeStepUndoneException());
                            return false;
                        }
                    }
                }
            }
            //系统用户默认拥有权限
            if (SystemUser.SYSTEM.getUserUuid().equals(userUuid)) {
                return true;
            }
            //14.判断当前用户是否是当前步骤的处理人，如果不是，则提示“您不是步骤处理人”；
            if (!checkIsProcessTaskStepUser(processTaskStepVo, ProcessUserType.MAJOR.getValue(), userUuid)) {
                operationTypePermissionDeniedExceptionMap.computeIfAbsent(id, key -> new HashMap<>())
                        .put(operationType, new ProcessTaskStepNotMajorUserException());
                return false;
            }
            return true;
        });
    }

    @Override
    public String getHandler() {
        return ChangeOperationAuthHandlerType.CHANGEHANDLE.getValue();
    }

    @Override
    public Map<ProcessTaskOperationType, TernaryPredicate<ProcessTaskVo, ProcessTaskStepVo, String, Map<Long, Map<ProcessTaskOperationType, ProcessTaskPermissionDeniedException>>, JSONObject>>
        getOperationBiPredicateMap() {
        return operationBiPredicateMap;
    }

}
